package org.jeecg.access.platform.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.access.constant.PlatformType;
import org.jeecg.access.entity.PlatformAccount;
import org.jeecg.access.platform.entity.BaseUserInfo;
import org.jeecg.access.platform.entity.BaseWorkData;
import org.jeecg.access.platform.entity.BiliUserInfo;
import org.jeecg.access.platform.entity.BiliWorkData;
import org.jeecg.access.platform.mapper.BiliUserInfoMapper;
import org.jeecg.access.platform.mapper.BiliWorksDataMapper;
import org.jeecg.access.platform.service.PlatformHandler;
import org.jeecg.access.platform.util.HttpRequestUtil;
import org.jeecg.access.platform.util.JsonParserUtils;
import org.jeecg.access.service.PlatformAccountService;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.util.UUIDGenerator;
import org.jeecg.util.DateTimeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * B站数据获取服务实现类（适配优化后抽象基类）
 * 遵循父类模板方法，使用JsonParserUtils解析节点，HttpRequestUtil发送请求，不使用流式/函数式编程
 */
@Slf4j
@Service
public class BiliGetDataServiceImpl extends AbstractGetDataServiceImpl implements PlatformHandler {

    // 数据访问层依赖
    private final BiliUserInfoMapper userInfoMapper;
    private final BiliWorksDataMapper worksDataMapper;

    private final PlatformAccountService platformAccountService;

    // 配置参数
    @Value("${more.token}")
    private String token;
    @Value("${more.bili.userInfo}")
    private String userInfoUrl;
    @Value("${more.bili.userVideos}")
    private String userVideosUrl;
    @Value("${more.bili.videoData}")
    private String videoDataUrl;

    /**
     * 构造方法注入依赖（适配父类构造参数）
     */
    @Autowired
    public BiliGetDataServiceImpl(
            BiliUserInfoMapper userInfoMapper,
            BiliWorksDataMapper worksDataMapper,
            com.fasterxml.jackson.databind.ObjectMapper objectMapper,
            HttpRequestUtil httpRequestUtil,
            PlatformAccountService platformAccountService
    ) {
        super(httpRequestUtil, objectMapper);
        this.userInfoMapper = userInfoMapper;
        this.worksDataMapper = worksDataMapper;
        this.platformAccountService = platformAccountService;
    }

    // ========================== 用户信息同步实现 ==========================

    /**
     * 1. 从数据库查询待同步的B站用户列表
     */
    @Override
    protected List<? extends BaseUserInfo> fetchUserInfoList() {
        List<BiliUserInfo> userInfos = userInfoMapper.getUserInfos();
        if (userInfos == null) {
            log.warn("查询B站用户信息返回null，返回空列表");
            return new ArrayList<>();
        }
        return userInfos;
    }

    /**
     * 2. 为单个用户创建请求头（返回Map格式）
     */
    @Override
    protected Map<String, String> createUserRequestHeaders(BaseUserInfo user) {
        Map<String, String> headers = new HashMap<>(2); // 预设容量减少扩容
        headers.put("Authorization", token);
        headers.put("Content-Type", "application/json");
        return headers;
    }

    /**
     * 3. 组装用户信息请求报文（JSON字符串）
     */
    @Override
    protected String buildUserRequestData(BaseUserInfo user) {
        if (!(user instanceof BiliUserInfo)) {
            log.warn("用户类型不是BiliUserInfo，无法组装请求体");
            return "";
        }
        BiliUserInfo biliUser = (BiliUserInfo) user;
        Map<String, String> requestMap = new HashMap<>(2);
        requestMap.put("uid", biliUser.getUserId() != null ? biliUser.getUserId() : "");
        requestMap.put("proxy", "");
        try {
            // 修复：使用父类继承的objectMapper字段，而非getter方法
            return objectMapper.writeValueAsString(requestMap);
        } catch (JsonProcessingException e) {
            log.error("组装用户请求体失败", e);
            return "";
        }
    }

    /**
     * 4. 获取用户信息API的URL
     */
    @Override
    protected String getUserApiUrl(BaseUserInfo user) {
        return userInfoUrl;
    }

    /**
     * 5. 获取用户信息的请求方法
     */
    @Override
    protected String getUserRequestMethod() {
        return "POST";
    }

    /**
     * 6. 创建用户信息请求的重试决策器
     * 统一校验：HTTP状态码+后续需使用的数据节点是否有效
     */
    @Override
    protected HttpRequestUtil.RetryDecision createUserRetryDecision(BaseUserInfo user) {
        return new BiliUserRetryDecision();
    }

    /**
     * B站用户信息重试决策器（增强版）
     * 校验逻辑：
     * 1. HTTP状态码非200时重试
     * 2. 响应中后续需使用的核心数据节点（data）无效时重试
     */
    private class BiliUserRetryDecision implements HttpRequestUtil.RetryDecision {
        @Override
        public boolean needRetry(int responseCode, String response) {
            // 1. HTTP状态码校验
            if (responseCode < 200 || responseCode >= 300) {
                log.debug("用户请求HTTP状态码异常({})，需要重试", responseCode);
                return true;
            }

            // 2. 核心数据节点校验（后续需使用data节点）
            try {
                // 检查data节点是否存在且有效
                Boolean isDataValid = JsonParserUtils.isNodeValid(response, "data");

                // 数据节点无效时需要重试
                if (!isDataValid) {
                    log.debug("用户请求核心数据节点(data)无效，需要重试");
                    return true;
                }

                // 3. 业务错误标识校验
                String errorMsg = JsonParserUtils.getStringValueFromString(response, "msg");
                if (errorMsg != null && !errorMsg.isEmpty()
                        && !"success".equalsIgnoreCase(errorMsg)
                        && !"ok".equalsIgnoreCase(errorMsg)
                        && !"0".equals(errorMsg)) {
                    log.debug("用户请求返回业务错误({})，需要重试", errorMsg);
                    return true;
                }
            } catch (Exception e) {
                log.error("解析用户响应失败，需要重试", e);
                return true;
            }
            return false;
        }
    }

    /**
     * 7. 解析用户响应报文并更新用户信息（使用JsonParserUtils）
     */
    @Override
    protected BaseUserInfo parseUserResponse(BaseUserInfo originalUser, String response) {
        if (!(originalUser instanceof BiliUserInfo)) {
            throw new IllegalArgumentException("原始用户类型不是BiliUserInfo");
        }
        BiliUserInfo user = (BiliUserInfo) originalUser;

        // 使用JsonParserUtils直接解析响应字符串
        user.setName(JsonParserUtils.getStringValueFromString(response, "data.space.info.name"));
        user.setSign(JsonParserUtils.getStringValueFromString(response, "data.space.info.sign"));
        user.setFollowing(JsonParserUtils.getIntValueFromString(response, "data.stat.following"));
        user.setFollower(JsonParserUtils.getIntValueFromString(response, "data.stat.follower"));
        user.setChargeNum(JsonParserUtils.getIntValueFromString(response, "data.space.info.elec.show_info.total"));

        return user;
    }

    /**
     * 8. 批量更新用户信息到数据库（传统循环）
     */
    @Override
    protected void batchUpdateUserInfo(List<? extends BaseUserInfo> successUserList) {
        List<BiliUserInfo> biliUsers = new ArrayList<>(successUserList.size());
        for (int i = 0; i < successUserList.size(); i++) {
            BaseUserInfo baseUser = successUserList.get(i);
            if (baseUser instanceof BiliUserInfo) {
                biliUsers.add((BiliUserInfo) baseUser);
            } else {
                log.warn("第{}条用户信息类型不符，跳过批量更新", i + 1);
            }
        }
        if (!biliUsers.isEmpty()) {
            int updateCount = userInfoMapper.batchUpSert(biliUsers);
            log.info("批量更新B站用户信息完成，共{}条，实际影响{}行", biliUsers.size(), updateCount);
        }
    }

    // ========================== 作品数据同步实现 ==========================

    /**
     * 创建作品数据请求的重试决策器（增强版）
     */
    @Override
    protected HttpRequestUtil.RetryDecision createWorkRetryDecision(BaseWorkData workData) {
        return new BiliWorkRetryDecision();
    }

    /**
     * B站作品重试决策器（增强版）
     * 校验逻辑：
     * 1. HTTP状态码非200时重试
     * 2. 响应中后续需使用的核心数据节点（data.videoData）无效时重试
     */
    private class BiliWorkRetryDecision implements HttpRequestUtil.RetryDecision {
        @Override
        public boolean needRetry(int responseCode, String response) {
            // 1. HTTP状态码校验
            if (responseCode < 200 || responseCode >= 300) {
                log.debug("作品请求HTTP状态码异常({})，需要重试", responseCode);
                return true;
            }

            // 2. 核心数据节点校验（后续需使用data.videoData节点）
            try {

                Boolean isBusinessSuccess = JsonParserUtils.isSuccess(response);
                if (isBusinessSuccess == null || !isBusinessSuccess) {
                    log.debug("作品请求业务响应失败，需要重试");
                    return true;
                }


                Integer videoData = JsonParserUtils.getListLength(response, "data.list.vlist");
                if (videoData == null || videoData <= 0) {
                    log.debug("作品请求核心节点(data.list.vlist)无效或为空，需要重试");
                    return true;
                }

            } catch (Exception e) {
                log.error("解析作品响应失败，需要重试", e);
                return true;
            }
            return false;
        }
    }

    /**
     * 获取用户所有作品（分页查询，适配父类参数）
     */
    @Override
    protected List<? extends BaseWorkData> fetchUserAllWorks(BaseUserInfo userInfo, String nowTime,Integer dataNum) throws Exception {
        if (!(userInfo instanceof BiliUserInfo)) {
            log.warn("用户类型不是BiliUserInfo，无法获取作品列表");
            return new ArrayList<>();
        }
        BiliUserInfo biliUser = (BiliUserInfo) userInfo;
        Map<String, String> headers = createHeaders(userInfo);
        return fetchUserAllVideos(biliUser, headers, nowTime,dataNum);
    }

    /**
     * 批量更新作品数据到数据库（传统循环）
     */
    @Override
    protected void batchUpdateWorksData(List<? extends BaseWorkData> worksData) {
        List<BiliWorkData> biliWorks = new ArrayList<>(worksData.size());
        for (int i = 0; i < worksData.size(); i++) {
            BaseWorkData baseWork = worksData.get(i);
            if (baseWork instanceof BiliWorkData) {
                biliWorks.add((BiliWorkData) baseWork);
            } else {
                log.warn("第{}条作品信息类型不符，跳过批量更新", i + 1);
            }
        }
        if (!biliWorks.isEmpty()) {
            int updateCount = worksDataMapper.batchUpSert(biliWorks);
            log.info("批量更新B站作品数据完成，共{}条，实际影响{}行", biliWorks.size(), updateCount);
        }
    }

    /**
     * 构造作品相关API的请求头（Map格式）
     */
    @Override
    protected Map<String, String> createHeaders(BaseUserInfo userInfo) {
        Map<String, String> headers = new HashMap<>(2);
        headers.put("Authorization", token);
        headers.put("Content-Type", "application/json");
        return headers;
    }

    // ========================== 自定义业务方法（适配优化） ==========================

    /**
     * 获取用户所有视频（分页查询）
     */
    private List<BiliWorkData> fetchUserAllVideos(BiliUserInfo userInfo, Map<String, String> headers, String nowTime,Integer dataNum) {
        if (userInfo == null || userInfo.getUserId() == null) {
            log.error("用户ID为空，无法获取视频列表");
            return new ArrayList<>();
        }

        String uid = userInfo.getUserId();
        List<BiliWorkData> allWorksList = new ArrayList<>();

        try {
            // 获取第一页数据
            VideoPageResult firstPage = fetchVideoPage(userInfo, 1, headers, nowTime);
            if (firstPage == null) {
                log.error("B站用户 {} 第一页视频获取失败", uid);
                return allWorksList;
            }

            // 添加第一页数据
            allWorksList.addAll(firstPage.videoList);
            log.info("B站用户 {} 第1页获取 {} 条视频，共 {} 条", uid, firstPage.videoList.size(), firstPage.totalCount);

            // 更新用户作品总数
            userInfo.setWorksCount(firstPage.totalCount);

            if(null != dataNum && dataNum == 1){
                // 计算总页数（避免除零）
                int pageSize = firstPage.pageSize;
                if (pageSize <= 0) {
                    log.warn("用户 {} 分页大小无效（{}），停止分页查询", uid, pageSize);
                    return allWorksList;
                }
                int totalPages = (int) Math.ceil((double) firstPage.totalCount / pageSize);
                log.info("用户 {} 视频总页数：{}", uid, totalPages);

                // 传统for循环获取剩余页
                for (int currentPage = 2; currentPage <= totalPages; currentPage++) {
                    VideoPageResult pageResult = fetchVideoPage(userInfo, currentPage, headers, nowTime);
                    if (pageResult != null && !pageResult.videoList.isEmpty()) {
                        allWorksList.addAll(pageResult.videoList);
                        log.info("B站用户 {} 第 {} 页获取 {} 条视频", uid, currentPage, pageResult.videoList.size());
                    } else {
                        log.warn("B站用户 {} 第 {} 页无有效数据，跳过", uid, currentPage);
                    }
                }
            }
            compensateDetail(userInfo,allWorksList);

        } catch (Exception e) {
            log.error("获取B站用户 {} 视频列表失败: {}", uid, e.getMessage(), e);
        }

        return allWorksList;
    }

    /**
     * 获取单页视频数据
     */
    private VideoPageResult fetchVideoPage(BiliUserInfo userInfo, int pageNum, Map<String, String> headers, String nowTime) throws IOException {
        if (userInfo == null || userInfo.getUserId() == null || pageNum < 1) {
            throw new IllegalArgumentException("无效的用户ID或页码（uid=" + userInfo.getUserId() + ", page=" + pageNum + "）");
        }

        // 构造请求体
        String requestBody = createVideoPageRequestBody(userInfo.getUserId(), pageNum);
        if (requestBody.isEmpty()) {
            throw new IOException("视频分页请求体为空");
        }

        // 调用HTTP工具类发送请求（带重试）
        String responseData = httpRequestUtil.sendRequest(
                userVideosUrl,
                "POST",
                headers,
                requestBody,
                new BiliWorkRetryDecision() // 使用作品重试决策器
        );

        if (responseData == null || responseData.isEmpty()) {
            throw new IOException("视频列表API返回空数据");
        }

        // 解析分页信息（使用JsonParserUtils）
        int pageSize = JsonParserUtils.getIntValueFromString(responseData, "data.page.ps");
        int totalCount = JsonParserUtils.getIntValueFromString(responseData, "data.page.count");

        // 解析视频列表
        List<BiliWorkData> videoList = parseVideoList(responseData, userInfo.getId(), nowTime);

        return new VideoPageResult(pageSize, totalCount, videoList);
    }

    /**
     * 补充作品详细数据（循环处理workDataList，通过videoDataUrl请求详细信息）
     * @param userInfo 用户信息（用于构建请求上下文）
     * @param workDataList 待补充详细数据的作品列表
     */
    private void compensateDetail(BiliUserInfo userInfo, List<BiliWorkData> workDataList) {
        if (null == userInfo || userInfo.getUserId().isEmpty() ||
                null == workDataList || workDataList.isEmpty()) {
            log.warn("补充作品详情的参数无效，跳过处理");
            return;
        }

        String userId = userInfo.getUserId();
        Map<String, String> headers = createHeaders(userInfo); // 复用请求头构建方法

        // 传统for循环处理作品列表（不使用流式编程）
        for (int i = 0; i < workDataList.size(); i++) {
            BiliWorkData workData = workDataList.get(i);
            if (workData == null) {
                log.warn("用户[{}]的第{}个作品数据为空，跳过", userId, i + 1);
                continue;
            }

            // 获取作品唯一标识
            String bvid = workData.getBvid();
            if (bvid == null ) {
                log.warn("用户[{}]的第{}个作品缺少bvid，无法补充详情", userId, i + 1);
                continue;
            }

            try {
                // 1. 构建详细数据请求体
                String requestBody = buildVideoDetailRequestBody(bvid);
                if (requestBody.isEmpty()) {
                    log.warn("用户[{}]的第{}个作品请求体构建失败，跳过", userId, i + 1);
                    continue;
                }

                // 2. 发送请求获取详细数据（使用作品重试决策器）
                String response = httpRequestUtil.sendRequest(
                        videoDataUrl,
                        "POST",
                        headers,
                        requestBody,
                        new WorkDetailRetryDecision()
                );

                // 3. 校验响应有效性
                if (response == null || response.trim().isEmpty()) {
                    log.warn("用户[{}]的第{}个作品详情响应为空，跳过", userId, i + 1);
                    continue;
                }

                // 4. 解析响应并补充作品详情
                parseAndFillDetail(workData, response);

                // 5. 更新最后补充时间
                log.debug("用户[{}]的第{}个作品详情补充完成", userId, i + 1);

            } catch (Exception e) {
                // 单个作品处理失败不影响整体循环
                log.error("用户[{}]的第{}个作品详情补充失败: {}", userId, i + 1, e.getMessage(), e);
            }
        }
    }

    /**
     * B站作品重试决策器（增强版）
     * 校验逻辑：
     * 1. HTTP状态码非200时重试
     * 2. 响应中后续需使用的核心数据节点（data.videoData）无效时重试
     */
    private class WorkDetailRetryDecision implements HttpRequestUtil.RetryDecision {
        @Override
        public boolean needRetry(int responseCode, String response) {
            // 1. HTTP状态码校验
            if (responseCode < 200 || responseCode >= 300) {
                log.debug("作品请求HTTP状态码异常({})，需要重试", responseCode);
                return true;
            }

            // 2. 核心数据节点校验（后续需使用data.videoData节点）
            try {

                Boolean isBusinessSuccess = JsonParserUtils.isSuccess(response);
                if (isBusinessSuccess == null || !isBusinessSuccess) {
                    log.debug("作品请求业务响应失败，需要重试");
                    return true;
                }

                 Boolean isDataValid = JsonParserUtils.isNodeValid(response, "data.videoData.stat");
                if (!isDataValid ) {
                    log.debug("作品请求核心节点(data.videoData.stat)无效或为空，需要重试");
                    return true;
                }
            } catch (Exception e) {
                log.error("解析作品响应失败，需要重试", e);
                return true;
            }
            return false;
        }
    }

    /**
     * 构建作品详细数据请求体
     * @param bvid 作品bvid（优先）
     * @return 请求体JSON字符串
     */
    private String buildVideoDetailRequestBody(String bvid) {
        Map<String, String> requestMap = new HashMap<>(2);
        requestMap.put("bvid", bvid);
        requestMap.put("proxy", "");

        try {
            return objectMapper.writeValueAsString(requestMap);
        } catch (JsonProcessingException e) {
            log.error("构建作品详情请求体失败（bvid={}, aid={}）", bvid, e);
            return "";
        }
    }

    /**
     * 解析详细数据响应并填充到作品对象
     * @param workData 待填充的作品对象
     * @param response 接口响应数据
     */
    private void parseAndFillDetail(BiliWorkData workData, String response) {
        // 补充播放量（可能包含更精确的数值）
        Integer precisePlay = JsonParserUtils.getIntValueFromString(response, "data.videoData.stat.view");
        if (precisePlay != null && precisePlay > 0) {
            workData.setPlay(precisePlay);
        }

        // 补充点赞数
        workData.setLikeCount(JsonParserUtils.getIntValueFromString(response, "data.videoData.stat.like"));
        // 补充收藏数
        workData.setFavorite(JsonParserUtils.getIntValueFromString(response, "data.videoData.stat.favorite"));
        // 补充分享数
        workData.setShareCount(JsonParserUtils.getIntValueFromString(response, "data.videoData.stat.share"));
        // 补充弹幕数
        workData.setVideoReview(JsonParserUtils.getIntValueFromString(response, "data.videoData.stat.danmaku"));
        //投币数
        workData.setCoin(JsonParserUtils.getIntValueFromString(response, "data.videoData.stat.coin"));
        // 补充发布时间（可能包含更精确的时间戳）
        Long publishTimestamp = JsonParserUtils.getLongValueFromString(response, "data.videoData.pubdate");
        if (null != publishTimestamp && publishTimestamp > 0l) {
            workData.setCreateTime(DateTimeUtil.convertTimestampToFormat(publishTimestamp));
        }
    }

    /**
     * 创建视频分页请求体（JSON字符串）
     */
    private String createVideoPageRequestBody(String uid, int pageNum) {
        Map<String, String> requestMap = new HashMap<>(6);
        requestMap.put("uid", uid);
        requestMap.put("tid", "0");
        requestMap.put("keyword", "");
        requestMap.put("order", "pubdate");
        requestMap.put("page", String.valueOf(pageNum));
        requestMap.put("proxy", "");
        try {
            // 修复：使用父类继承的objectMapper字段
            return objectMapper.writeValueAsString(requestMap);
        } catch (JsonProcessingException e) {
            log.error("组装视频分页请求体失败", e);
            return "";
        }
    }

    /**
     * 解析视频列表（使用JsonParserUtils，传统循环）
     */
    private List<BiliWorkData> parseVideoList(String response, String userId, String nowTime) {
        List<BiliWorkData> worksList = new ArrayList<>();
        if (response == null || userId == null) {
            log.error("解析参数为空（response={}, userId={}）", response, userId);
            return worksList;
        }

        // 获取视频数组长度（修复方法名）
        Integer videoCount = JsonParserUtils.getListLength(response, "data.list.vlist");
        if (videoCount <= 0) {
            log.debug("用户 {} 视频列表为空", userId);
            return worksList;
        }

        // 传统for循环解析每个视频（按索引访问数组）
        for (int i = 0; i < videoCount; i++) {
            String basePath = "data.list.vlist[" + i + "]"; // 数组元素路径

            BiliWorkData workData = new BiliWorkData();
            workData.setId(UUIDGenerator.generate());
            workData.setUserId(userId);
            workData.setUpdateTime(nowTime); // 统一设置更新时间

            // 使用JsonParserUtils解析每个字段
            workData.setAid(JsonParserUtils.getStringValueFromString(response, basePath + ".aid"));
            workData.setBvid(JsonParserUtils.getStringValueFromString(response, basePath + ".bvid"));
            workData.setTitle(JsonParserUtils.getStringValueFromString(response, basePath + ".title"));
            workData.setDescription(JsonParserUtils.getStringValueFromString(response, basePath + ".description"));
            workData.setCommentCount(JsonParserUtils.getIntValueFromString(response, basePath + ".comment"));
            workData.setPlay(JsonParserUtils.getIntValueFromString(response, basePath + ".play"));
            workData.setVideoReview(JsonParserUtils.getIntValueFromString(response, basePath + ".video_review"));

            // 处理创建时间
            int createdTimestamp = JsonParserUtils.getIntValueFromString(response, basePath + ".created");
            if (createdTimestamp <= 0) {
                log.warn("用户 {} 视频{}的created时间戳无效（{}）", userId, i + 1, createdTimestamp);
                workData.setCreateTime(null);
            } else {
                workData.setCreateTime(DateTimeUtil.convertTimestampToFormat(createdTimestamp));
            }

            worksList.add(workData);
        }

        return worksList;
    }

    // ========================== PlatformHandler接口实现 ==========================

    @Override
    public List<?> fetchExternalData() {
        List<BiliUserInfo> localUserList = userInfoMapper.getUserInfos();
        if (localUserList == null) {
            log.warn("本地B站用户表查询返回null，返回空列表");
            return new ArrayList<>();
        }
        log.info("从本地B站用户表获取到 {} 条已有数据", localUserList.size());
        return localUserList;
    }

    @Override
    public String extractAccountId(Object data) {
        if (data == null || !(data instanceof BiliUserInfo)) {
            log.warn("本地用户数据格式无效，无法提取账号ID");
            return null;
        }
        BiliUserInfo localUser = (BiliUserInfo) data;
        return localUser.getId();
    }

    @Override
    public boolean verifyAccount(PlatformAccount account) {
        if (account == null || account.getAccountId() == null || account.getAccountId().trim().isEmpty()) {
            log.warn("待校验账号信息无效（ID为空）");
            return false;
        }

        String uid = account.getAccountId().trim();
        BiliUserInfo userInfo = new BiliUserInfo();

        Map<String, String> headers = createHeaders(userInfo);
        try {
            // 构建请求体
            String requestBody = buildVerifyAccountRequestBody(uid);
            if (requestBody.isEmpty()) {
                log.error("账号校验请求体为空");
                return false;
            }

            // 发送请求（使用HttpRequestUtil）
            String response = httpRequestUtil.sendRequest(
                    userInfoUrl,
                    "POST",
                    headers,
                    requestBody,
                    new BiliUserRetryDecision()
            );

            if (response == null || response.trim().isEmpty()) {
                log.warn("账号[{}]校验失败：B站API返回空数据", uid);
                return false;
            }

            log.info("账号[{}]校验成功：在B站真实存在", uid);
            return true;
        } catch (Exception e) {
            log.error("账号[{}]校验失败：B站API请求异常", uid, e);
            return false;
        }
    }

    /**
     * 构建账号校验请求体
     */
    private String buildVerifyAccountRequestBody(String uid) {
        Map<String, String> requestMap = new HashMap<>(2);
        requestMap.put("uid", uid);
        requestMap.put("proxy", "");
        try {
            // 修复：使用父类继承的objectMapper字段
            return objectMapper.writeValueAsString(requestMap);
        } catch (JsonProcessingException e) {
            log.error("组装账号校验请求体失败", e);
            return "";
        }
    }

    @Override
    public void writeToExternalSystem(PlatformAccount account) {
        if (account == null || account.getAccountId() == null || account.getAccountId().trim().isEmpty()) {
            log.warn("待同步账号信息无效（ID为空）");
            return;
        }

        String uid = account.getAccountId().trim();
        String nowTime = DateTimeUtil.getCurrentTimestamp();
        BiliUserInfo userInfo = new BiliUserInfo();
        userInfo.setUserId(uid);
        userInfo.setCreateTime(account.getCreateTime());
        userInfo.setUpdateTime(nowTime);
        userInfo.setState(account.getState());
        userInfo.setId(account.getId());

        userInfoMapper.insert(userInfo);
        log.info("账号[{}]已同步到本地B站用户表", uid);
    }

    @Override
    public String verifyAddedAccount(PlatformAccount account) {
        if (null == account.getAccountId() || account.getAccountId().trim().isEmpty()) {
            return "哔哩哔哩账号的accountId不能为空";
        }

        QueryWrapper<PlatformAccount> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("platform_type", account.getPlatformType());
        queryWrapper.eq("account_id", account.getAccountId());
        int count = platformAccountService.count(queryWrapper);
        if (count > 0) {
           return "哔哩哔哩账号的accountId账号已存在";
        }
        return null;
    }


    @Override
    public String getPlatformType() {
        return PlatformType.BILIBILI.getCode();
    }

    /**
     * 内部类：封装视频分页结果
     */
    private static class VideoPageResult {
        final int pageSize;       // 每页条数
        final int totalCount;     // 总条数
        final List<BiliWorkData> videoList;  // 本页视频列表

        VideoPageResult(int pageSize, int totalCount, List<BiliWorkData> videoList) {
            this.pageSize = pageSize;
            this.totalCount = totalCount;
            this.videoList = videoList != null ? videoList : new ArrayList<>();
        }
    }
}